package com.bbex.controller;

import com.bbex.config.sercurity.RedisSessionUser;
import com.bbex.constant.Constants;
import com.bbex.entity.*;
import com.bbex.pojo.GlobalMessageResponseVo;
import com.bbex.pojo.ResponsePage;
import com.bbex.service.CoinService;
import com.bbex.service.HongmengCoinHidVolumeService;
import com.bbex.service.HongmengCoinVolumeService;
import com.bbex.service.UserCoinVolumeExService;
import com.bbex.valid.ValidateFiled;
import com.bbex.valid.ValidateGroup;
import com.bbex.vo.*;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 用户资产相关操作
 */
@RestController
@RequestMapping("/bbuni")
public class UserCoinVolumeController {
    @Autowired
    private UserCoinVolumeExService userCoinVolumeExService;
    @Autowired
    private CoinService coinService;

    @Autowired
    private HongmengCoinVolumeService hongmengCoinVolumeService;
    @Autowired
    private HongmengCoinHidVolumeService hongmengCoinHidVolumeService;

    private static final Logger LOGGER = LoggerFactory.getLogger(UserCoinVolumeController.class);

    /**
     * 用户资产列表
     *
     * @return
     */
    @GetMapping("/coin/volume/list")
    public Mono<GlobalMessageResponseVo> findAll() {

        Mono<SecurityContext> context
                = ReactiveSecurityContextHolder.getContext();

        return context.filter(c -> Objects.nonNull(c.getAuthentication()))
                .map(s -> s.getAuthentication().getPrincipal())
                .cast(RedisSessionUser.class)
                .map(e -> {
                    //查找coin所有币种
                    List<Coin> list = coinService.findAll();
                    List<CoinVolumeVO> listVo = new ArrayList<>(5);
                    list.forEach(coin -> {
                        CoinVolumeVO coinVolumeVO = new CoinVolumeVO();
                        BeanUtils.copyProperties(coin, coinVolumeVO);
                        listVo.add(coinVolumeVO);

                    });
                    List<HongmengCoinVolume> listVolume = hongmengCoinVolumeService.findAll(e.getId());
                    if (CollectionUtils.isNotEmpty(listVolume)) {
                        for (CoinVolumeVO coinVolumeVO : listVo) {
                            for (HongmengCoinVolume hongmengCoinVolume : listVolume) {
                                if (hongmengCoinVolume != null) {
                                    if (hongmengCoinVolume.getCoinId().equals(coinVolumeVO.getId())) {
                                        String id = coinVolumeVO.getId();
                                        hongmengCoinVolume.setWithdrawFee(coinVolumeVO.getWithdrawFee());
                                        BeanUtils.copyProperties(hongmengCoinVolume, coinVolumeVO);
                                        coinVolumeVO.setId(id);
                                    }
                                }
                            }
                        }
                    }
                    //返回用户持有资产
                    return GlobalMessageResponseVo.newSuccessInstance(listVo);
                });
    }

    /**
     * 用户hid账户资产列表
     *
     * @return
     */
    @GetMapping("/coin/volume/hid/list")
    public Mono<GlobalMessageResponseVo> findHidAll() {

        Mono<SecurityContext> context
                = ReactiveSecurityContextHolder.getContext();

        return context.filter(c -> Objects.nonNull(c.getAuthentication()))
                .map(s -> s.getAuthentication().getPrincipal())
                .cast(RedisSessionUser.class)
                .map(e -> {
                    //查找coin所有币种
                    List<Coin> list = coinService.findAll();
                    List<CoinVolumeVO> listVo = new ArrayList<>(5);
                    list.forEach(coin -> {
                        CoinVolumeVO coinVolumeVO = new CoinVolumeVO();
                        BeanUtils.copyProperties(coin, coinVolumeVO);
                        listVo.add(coinVolumeVO);

                    });
                    List<HongmengCoinHidVolume> listVolume = hongmengCoinHidVolumeService.findHidAll(e.getId());
                    if (CollectionUtils.isNotEmpty(listVolume)) {
                        for (CoinVolumeVO coinVolumeVO : listVo) {
                            for (HongmengCoinHidVolume hongmengCoinHidVolume : listVolume) {
                                if (hongmengCoinHidVolume != null) {
                                    if (hongmengCoinHidVolume.getCoinId().equals(coinVolumeVO.getId())) {
                                        BeanUtils.copyProperties(hongmengCoinHidVolume, coinVolumeVO);
                                    }
                                }
                            }
                        }
                    }
                    return GlobalMessageResponseVo.newSuccessInstance(listVolume);
                });
    }

    /**
     * 资产划转
     *
     * @return
     */
    @ValidateGroup(fileds = {
            @ValidateFiled(index = 0, filedName = "coinId", notNull = true, errMsg = "币种id不能为空"),
            @ValidateFiled(index = 0, filedName = "symbol", notNull = true, errMsg = "币种符号不能为空"),
            @ValidateFiled(index = 0, filedName = "volume", notNull = true, errMsg = "币种数量不能为空"),
            @ValidateFiled(index = 0, filedName = "from", notNull = true, errMsg = "from不能为空"),
            @ValidateFiled(index = 0, filedName = "to", notNull = true, errMsg = "to不能为空"),
    })
    @PostMapping("/hid/volume/inOut")
    public Mono<GlobalMessageResponseVo> inOut(HidTransferVO hidTransferVO) {
        if (hidTransferVO.getVolume().compareTo(BigDecimal.ZERO) == -1) {
            return Mono.just(GlobalMessageResponseVo.newErrorInstance("转入数量非法"));
        }
        return ReactiveSecurityContextHolder.getContext()
                .filter(c -> c.getAuthentication() != null)
                .map(SecurityContext::getAuthentication).map(Authentication::getPrincipal).cast(RedisSessionUser.class).flatMap(user -> {
                    LOGGER.info("用户划转参数：" + "volume:" + hidTransferVO.getVolume() + " from:" + hidTransferVO.getFrom() + " to:" + hidTransferVO.getTo() + " source:" + user.getLoginSource());
                    if (hidTransferVO.getFrom().equals(hidTransferVO.getTo())) {
                        return Mono.just(GlobalMessageResponseVo.newInstance(Constants.VOLUME_IN_OUT_ERROR, "转入转出类型错误，不能选同类"));
                    }

                    //确保coinId与coinSymbol一致
                    Coin coin = coinService.findById(hidTransferVO.getCoinId());
                    if(Objects.isNull(coin)){
                        return Mono.just(GlobalMessageResponseVo.newInstance(Constants.VOLUME_IN_OUT_ERROR, "参数异常"));
                    }
                    hongmengCoinHidVolumeService.inOut(user.getId(), hidTransferVO.getCoinId(), hidTransferVO.getVolume(), coin.getName(), hidTransferVO.getFrom(), hidTransferVO.getTo(), null);
                    return Mono.just(GlobalMessageResponseVo.newSuccessInstance("转入成功"));
                });
    }

    /**
     * 用户资金划转记录
     * @return
     */
    @PostMapping("/coin/coinOut/list")
    public Mono<GlobalMessageResponseVo> coinOutList(CoinoutListVO coinoutListVO) {

        Mono<SecurityContext> context
                = ReactiveSecurityContextHolder.getContext();

        return context.filter(c -> Objects.nonNull(c.getAuthentication()))
                .map(s -> s.getAuthentication().getPrincipal())
                .cast(RedisSessionUser.class)
                .map(e -> {
                    String userId = e.getId();
                    coinoutListVO.setUserId(userId);
                    return GlobalMessageResponseVo.newSuccessInstance(hongmengCoinHidVolumeService.findCoinoutLogPage(coinoutListVO));

                });
    }

    /**
     * 获取bb对应的币种资产
     *
     * @return
     */

    /*@GetMapping("/coin/volume/{coinId}")
    public Mono<GlobalMessageResponseVo> coinVolume(@PathVariable("coinId") String coinId) {
        return ReactiveSecurityContextHolder.getContext()
                .filter(c -> c.getAuthentication() != null)
                .map(SecurityContext::getAuthentication)
                .map(Authentication::getPrincipal)
                .cast(RedisSessionUser.class)
                .flatMap(user -> Mono
                        .just(GlobalMessageResponseVo.newSuccessInstance(userCoinVolumeExService.findByUserIdAndCoinId(user.getId(), coinId)
                        )));
    }*/

    /**
     * 获取bb对应的币种资产
     *
     * @return
     */

    /*@GetMapping("/coin/volume/symbol/{coinSymbol}")
    public Mono<GlobalMessageResponseVo> coinSymbol(@PathVariable("coinSymbol") String coinSymbol) {
        return ReactiveSecurityContextHolder.getContext()
                .filter(c -> c.getAuthentication() != null)
                .map(SecurityContext::getAuthentication)
                .map(Authentication::getPrincipal)
                .cast(RedisSessionUser.class)
                .flatMap(user -> Mono
                        .just(GlobalMessageResponseVo.newSuccessInstance(userCoinVolumeExService.findByUserIdAndCoinSymbol(user.getId(), coinSymbol)
                        )));
    }*/

}
